﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

[assembly: WebResource("ExtJSExtender.Controls.DateField.DateFieldExtenderBehavior.js", "text/javascript")]

namespace ExtJSExtender.Controls
{
    [ToolboxBitmap(typeof(System.Web.UI.WebControls.TextBox))]
    public class DateField : ExtJSControlBase, IPostBackEventHandler, INamingContainer, ICallbackEventHandler, IPostBackDataHandler
    {
        #region 属性

        /// <summary>
        /// 是否自动回发
        /// </summary>
        [ExtJSExtender.DescribableProperty("AutoPostBack")]
        public bool AutoPostBack
        {
            get
            {
                if (ViewState["AutoPostBack"] == null)
                    ViewState["AutoPostBack"] = false;
                return (bool)ViewState["AutoPostBack"];
            }
            set
            {
                ViewState["AutoPostBack"] = value;
            }
        }

        /// <summary>
        /// 是否允许空值
        /// </summary>
        [ExtJSExtender.DescribableProperty("AllowBlank")]
        public bool AllowBlank
        {
            get
            {
                if (ViewState["AllowBlank"] == null)
                    ViewState["AllowBlank"] = false;
                return (bool)ViewState["AllowBlank"];
            }
            set
            {
                ViewState["AllowBlank"] = value;
            }
        }

        /// <summary>
        /// 控件的值
        /// </summary>
        [ExtJSExtender.DescribableProperty("Value")]
        public DateTime? Value
        {
            get
            {
                if (ViewState["Value"] == null)
                    return null;

                return (DateTime)ViewState["Value"];
            }
            set
            {
                ViewState["Value"] = value;
                if (value.HasValue)
                    this.text = value.Value.ToString("yyyy-MM-dd");
                else
                    this.text = string.Empty;
            }
        }

        private string text = string.Empty;
        /// <summary>
        /// 控件的文本内容
        /// </summary>
        public string Text
        {
            get
            {
                return text;
            }
        }

        /// <summary>
        /// 格式化字符串
        /// 日期格式字符串说明参见：http://www.cnblogs.com/youring2/archive/2013/02/21/2920943.html
        /// </summary>
        [ExtJSExtender.DescribableProperty("FormatString")]
        public string FormatString
        {
            get
            {
                if (ViewState["FormatString"] == null)
                    ViewState["FormatString"] = "Y-m-d";
                return (string)ViewState["FormatString"];
            }
            set
            {
                ViewState["FormatString"] = value;
            }
        }

        /// <summary>
        /// 其它的格式化字符串，在输入时用于转化为日期格式
        /// 每个格式化字符串用"|"隔开
        /// </summary>
        [ExtJSExtender.DescribableProperty("AltFormatsString")]
        public string AltFormatsString
        {
            get
            {
                if (ViewState["AltFormatsString"] == null)
                    ViewState["AltFormatsString"] = "Y-n-j|Y-m-j|Y-n-d|Ymd";
                return (string)ViewState["AltFormatsString"];
            }
            set
            {
                ViewState["AltFormatsString"] = value;
            }
        }

        /// <summary>
        /// 获得焦点后选中
        /// </summary>
        [ExtJSExtender.DescribableProperty("SelectOnFocus")]
        public bool SelectOnFocus
        {
            get
            {
                if (ViewState["SelectOnFocus"] == null)
                    ViewState["SelectOnFocus"] = false;
                return (bool)ViewState["SelectOnFocus"];
            }
            set
            {
                ViewState["SelectOnFocus"] = value;
            }
        }
        /// <summary>
        /// 最小值
        /// </summary>
        [ExtJSExtender.DescribableProperty("MinValue")]
        public DateTime? MinValue
        {
            get
            {
                if (ViewState["MinValue"] == null)
                    return null;
                return (DateTime)ViewState["MinValue"];
            }
            set
            {
                ViewState["MinValue"] = value;
            }
        }
        /// <summary>
        /// 最大值
        /// </summary>
        [ExtJSExtender.DescribableProperty("MaxValue")]
        public DateTime? MaxValue
        {
            get
            {
                if (ViewState["MaxValue"] == null)
                    return null;
                return (DateTime)ViewState["MaxValue"];
            }
            set
            {
                ViewState["MaxValue"] = value;
            }
        }

        /// <summary>
        /// 边框的宽度
        /// </summary>
        public Unit Border
        {
            get
            {
                if (ViewState["Border"] == null)
                    ViewState["Border"] = new Unit(1);
                return (Unit)ViewState["Border"];
            }
            set
            {
                ViewState["Border"] = value;
            }
        }

        [ExtJSExtender.DescribableProperty("TriggerPostBackEvents")]
        [PersistenceMode(PersistenceMode.InnerProperty), Bindable(true), Localizable(true)]
        public DateFeildTriggerPostBackEvents TriggerPostBackEvents
        {
            get
            {
                if (ViewState["TriggerPostBackEvents"] == null)
                    ViewState["TriggerPostBackEvents"] = new DateFeildTriggerPostBackEvents();

                return (DateFeildTriggerPostBackEvents)ViewState["TriggerPostBackEvents"];
            }
            set
            {
                ViewState["TriggerPostBackEvents"] = value;
            }
        }

        #endregion

        #region 构造函数

        public DateField()
            : base(HtmlTextWriterTag.Div)
        {

        }

        #endregion

        #region 事件

        public event DateChangeEventHandler Change;

        #endregion

        #region 只读属性，处理控件的值及事件等

        [ExtJSExtender.DescribableProperty("ValueTextHiddenField")]
        public string ValueText_HiddenField_ClientID
        {
            get { return this.ClientID + "_ValueText"; }
        }

        #endregion

        #region WebControl 方法重写

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            //加载回发的数据
            this.LoadPostData(this.ClientID, this.Page.Request.Params);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            base.Render(writer);

            //在前台放一个隐藏域，用于存放从前台回发后台的数据
            Util.RenderHiddenField(writer, this.ValueText_HiddenField_ClientID,
                Value.HasValue ? Value.Value.ToString("yyyy-MM-dd") : string.Empty);
        }

        #endregion

        #region ExtScriptWebControlBase 成员

        public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        {
            ScriptControlDescriptor descriptor = new ScriptControlDescriptor("ExtJSExtender.Controls.DateFieldExtenderBehavior", this.ClientID);

            descriptor.AddProperty("Enabled", Enabled);
            descriptor.AddProperty("Width", this.Width.Value);
            descriptor.AddProperty("Height", this.Height.Value);
            descriptor.AddProperty("Border", this.Border.Value);
            descriptor.AddProperty("UniqueID", this.UniqueID);

            ExtJSExtender.Util.DescribeProperties(this, descriptor);

            var descriptors = base.GetScriptDescriptors().ToList();
            descriptors.Add(descriptor);
            return descriptors;
        }

        public override IEnumerable<ScriptReference> GetScriptReferences()
        {
            var reference = new ScriptReference();
            reference.Assembly = "ExtJSExtender.Controls";
            reference.Name = "ExtJSExtender.Controls.DateField.DateFieldExtenderBehavior.js";

            var references = base.GetScriptReferences().ToList();
            references.Add(reference);
            return references;
        }

        #endregion

        #region ICallbackEventHandler 成员

        public string GetCallbackResult()
        {
            return null;
        }

        public void RaiseCallbackEvent(string eventArgument)
        {
            ExtJSEventArgs extJSEventArgs = Util.DeserializeJson<ExtJSEventArgs>(eventArgument);
            if (extJSEventArgs == null)
                return;

            switch (extJSEventArgs.EventName)
            {
                case "Change":
                    {
                        if (this.Change != null)
                        {
                            DateChangeEventArgs args = Util.DeserializeJson<DateChangeEventArgs>(extJSEventArgs.Arguments);
                            this.Change.Invoke(this, args);
                        }
                    }
                    break;
            }
        }

        #endregion

        #region IPostBackEventHandler 成员

        public void RaisePostBackEvent(string eventArgument)
        {
            RaiseCallbackEvent(eventArgument);
        }

        #endregion

        #region IPostBackDataHandler 成员

        public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            if (Page.IsPostBack)
            {
                this.Value = null;
                this.text = Context.Request[this.ValueText_HiddenField_ClientID];
                if (!string.IsNullOrWhiteSpace(this.text))
                {
                    DateTime newValue;
                    if (DateTime.TryParse(this.text, out newValue))
                        this.Value = newValue;
                    else
                        this.Value = null;
                }
            }

            return false;
        }

        public void RaisePostDataChangedEvent()
        {
            //如果LoadPostData返回true，此方法将被调用，此处不处理
        }

        #endregion
    }
}
